package com.eibus.applicationconnector.twitter;

import java.util.HashMap;
import java.util.Map;

import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.conf.PropertyConfiguration;

import com.eibus.soap.Processor;
import com.eibus.util.logger.CordysLogger;
import com.eibus.util.logger.Severity;
import com.eibus.xml.nom.Node;
import com.eibus.xml.xpath.XPath;

public class TwitterConnector extends com.eibus.soap.ApplicationConnector {
	private Processor processor = null;
	public static int configurationNode = 0;
	public static final String serverFaultCode = "Server.Exception";
	public static final String clientFaultCode = "Client.Invalid";
	private static XPath configXPath = XPath
			.getXPathInstance("./configuration");
	private static final CordysLogger processorLogger = CordysLogger
			.getCordysLogger(TwitterConnector.class);
	private Map<String, ITwitterMethod> methodMap = new HashMap<String, ITwitterMethod>();

	private ApplicationConfiguration acConfig;
	private static final Class<?>[] methodClasses = {

	};
	

	public void open(Processor processor) {
		this.processor = processor;
		int configurationsNode = processor.getProcessorConfigurationNode();
		configurationNode = configXPath.firstMatch(configurationsNode, null);
		/*int filePath = configXPath.getFirstMatch("./configuration/file", null,
				configurationNode);*/
		

		processorLogger.log(
				Severity.DEBUG,
				"SOAP Processor configuration node: "
						+ Node.writeToString(configurationNode, true));
		
	     try {
			acConfig = new ApplicationConfiguration(getConfiguration());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
		try {
			loadSoapMethods();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void close(Processor processor) {
		if (processorLogger.isDebugEnabled())
			processorLogger.debug("Calling default close method");
	}

	public void reset(Processor processor) {
		if (processorLogger.isDebugEnabled())
			processorLogger.debug("Calling default reset method");

		for (ITwitterMethod method : methodMap.values()) {
			try {
				method.onReset();
			} catch (Exception e) {
				if (processorLogger.isDebugEnabled()) {
					processorLogger.debug(
							"SOAP method " + method.getMethodName()
									+ " reset failed.", e);
				}
			}
		}

	}

	public com.eibus.soap.ApplicationTransaction createTransaction(
			com.eibus.soap.SOAPTransaction soapTransaction) {
		
		return new TwitterTransaction(processor, soapTransaction, this);
	}

	private void loadSoapMethods() throws Exception {
		for (Class<?> methodClass : methodClasses) {
			Object obj = null;

			try {
				obj = methodClass.newInstance();
			} catch (Exception e) {
				throw new IllegalStateException(
						"Unable to load SOAP method class: "
								+ methodClass.getName());
			}

			if (!(obj instanceof ITwitterMethod)) {
				throw new IllegalStateException("SOAP method class: "
						+ methodClass.getName()
						+ " does not implement interface "
						+ ITwitterMethod.class.getName());
			}

			ITwitterMethod method = (ITwitterMethod) obj;

			try {
				if (method.initialize(acConfig)) {
					methodMap.put(method.getMethodName(), method);
				} else {
					if (processorLogger.isDebugEnabled()) {
						processorLogger.debug("SOAP method is not loaded: "
								+ methodClass.getName());
					}
				}
			}  catch (Exception e) {
				processorLogger.log(Severity.WARN, "SOAP method " + method.getMethodName()
						+ " initialization failed.", e);

				throw new IllegalStateException("SOAP method "
						+ method.getMethodName() + " initialization failed.", e);
			}
		}
	}
	
	/**
     * Returns a SOAP method implementation object from the configured methods.
     *
     * @param   name  Method name.
     *
     * @return  Implementation object.
     */
    public ITwitterMethod getMethod(String name)
    {
        return methodMap.get(name);
    }


}
